#include "apue.h"
#include <pthread.h>
#include "practice_11.5.head.c"
#include <stdarg.h>

extern void __pthread_barrier_destroy(__pthread_barrier_t *barrier);
extern void __pthread_barrier_wait(__pthread_barrier_t *barrier);
extern void __pthread_barrier_init(__pthread_barrier_t *barrier, unsigned int count);

__pthread_barrier_t pbt;

void thread_printf(pthread_t *pt, const char *format, ...) {
    va_list va;
    char str[MAXLINE];
    va_start(va, format);
    sprintf(str, "thread %lu: ", (long unsigned)pt);
    vsprintf(str+strlen(str), format, va);
    va_end(va);
    puts(str);
}

void *thr_fn(void *arg) {
    pthread_t pt;
    int s= (unsigned long)arg;

    pt= pthread_self();
    if (s > 0) {
        thread_printf(&pt, "I'm sleeping %d second\n", s);
        sleep(s);
    } else {
        thread_printf(&pt, "I'm running\n");
    }
    __pthread_barrier_wait(&pbt);
    thread_printf(&pt, "end");
    return (void *)0;
}

int main() {
    pthread_t p1, p2, p3, p4;
    __pthread_barrier_init(&pbt, 4);
    pthread_create(&p1, NULL, thr_fn, 0);
    pthread_create(&p2, NULL, thr_fn, 0);
    pthread_create(&p3, NULL, thr_fn, (void *)5);
    pthread_create(&p4, NULL, thr_fn, 0);

    pthread_join(p1, NULL);
    pthread_join(p2, NULL);
    pthread_join(p3, NULL);
    pthread_join(p4, NULL);

    printf("Main end\n");
}

